#ifndef LSM6DSO_H
#define LSM6DSO_H

#include <string.h>
#include "esp_log.h"
#include "esp_check.h"
#include "driver/i2c_master.h"
#include "driver/gpio.h"
#include "lsm6dso_reg.h"

typedef enum
{
  LSM6DSO_ACC_HIGH_PERFORMANCE_MODE,
  LSM6DSO_ACC_LOW_POWER_NORMAL_MODE,
  LSM6DSO_ACC_ULTRA_LOW_POWER_MODE
} LSM6DSO_ACC_Operating_Mode_t;

typedef enum
{
  LSM6DSO_GYRO_HIGH_PERFORMANCE_MODE,
  LSM6DSO_GYRO_LOW_POWER_NORMAL_MODE
} LSM6DSO_GYRO_Operating_Mode_t;

typedef struct
{
  gpio_num_t LSM6DSO_CS_PIN;
  gpio_num_t LSM6DSO_INT1_PIN;
  gpio_num_t LSM6DSO_INT2_PIN;
}LSM6DSO_SensorPin_t;

typedef struct
{
  LSM6DSO_SensorPin_t Pin;
  uint8_t Addr;
  uint32_t SCL_Speed;
  uint8_t is_initialized;
  bool timestamp_mode;
  LSM6DSO_ACC_Operating_Mode_t Acc_PowerMode;
  LSM6DSO_GYRO_Operating_Mode_t Gyro_PowerMode;
  lsm6dso_odr_xl_t Acc_odr;
  lsm6dso_odr_g_t Gyro_odr;
  lsm6dso_fs_xl_t Acc_fs;
  lsm6dso_fs_g_t Gyro_fs;
}LSM6DSO_Object_t;

typedef struct
{
    int16_t x;
    int16_t y;
    int16_t z;
}LSM6DSO_AxesRaw_t;

typedef struct
{
    float_t x;
    float_t y;
    float_t z;
}LSM6DSO_Axes_t;

typedef struct
{
  LSM6DSO_AxesRaw_t acc_raw;
  LSM6DSO_AxesRaw_t gyro_raw;
  LSM6DSO_Axes_t    acc;
  LSM6DSO_Axes_t    gyro;
  float_t           temp;
  uint32_t          timestamp;
}LSM6DSO_Data_t;


typedef struct
{
  unsigned int FreeFallStatus : 1;
  unsigned int TapStatus : 1;
  unsigned int DoubleTapStatus : 1;
  unsigned int WakeUpStatus : 1;
  unsigned int StepStatus : 1;
  unsigned int TiltStatus : 1;
  unsigned int D6DOrientationStatus : 1;
  unsigned int SleepStatus : 1;
}LSM6DSO_Event_Status_t;

esp_err_t lsm6dso_init(const i2c_master_bus_handle_t i2c_bus,i2c_master_dev_handle_t *dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_deinit(i2c_master_dev_handle_t *dev_handle,LSM6DSO_Object_t *pObj);

esp_err_t lsm6dso_get_id(const i2c_master_dev_handle_t dev_handle);
esp_err_t lsm6dso_get_data(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Data_t *data,const LSM6DSO_Object_t *pObj);

esp_err_t lsm6dso_temp_getdata(const i2c_master_dev_handle_t dev_handle,float_t *temp_data);

esp_err_t lsm6dso_timestamp_setmode(const i2c_master_dev_handle_t dev_handle,bool mode,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_timestamp_getdata(const i2c_master_dev_handle_t dev_handle,uint32_t *timestamp);

esp_err_t lsm6dso_acc_enable(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_acc_disable(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_acc_getpowermode(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_acc_setpowermode(const i2c_master_dev_handle_t dev_handle,LSM6DSO_ACC_Operating_Mode_t Mode,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_acc_getparams(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_acc_setparams(const i2c_master_dev_handle_t dev_handle,lsm6dso_odr_xl_t SAMPLE_SPEED,lsm6dso_fs_xl_t FULL_SCALE,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_acc_getaxes(const i2c_master_dev_handle_t dev_handle,LSM6DSO_AxesRaw_t *AxesRaw_t,LSM6DSO_Axes_t *Axes_t,const LSM6DSO_Object_t *pObj);

esp_err_t lsm6dso_gyro_enable(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_gyro_disable(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_gyro_getpowermode(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_gyro_setpowermode(const i2c_master_dev_handle_t dev_handle,LSM6DSO_GYRO_Operating_Mode_t Mode,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_gyro_getparams(const i2c_master_dev_handle_t dev_handle,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_gyro_setparams(const i2c_master_dev_handle_t dev_handle,lsm6dso_odr_g_t SAMPLE_SPEED,lsm6dso_fs_g_t FULL_SCALE,LSM6DSO_Object_t *pObj);
esp_err_t lsm6dso_gyro_getaxes(const i2c_master_dev_handle_t dev_handle,LSM6DSO_AxesRaw_t *AxesRaw_t,LSM6DSO_Axes_t *Axes_t,const LSM6DSO_Object_t *pObj);


#endif
